Fire Severity Analysis

Fire Severity Analysis in Guatemala Using Landsat 8/9 Imagery

Author

Joel Pimienta

Last Date Run

January 20, 2025

1 Introduction

Tutorial for calculating and plotting dNBR Fire Severity Index using Landsat 8/9 satellite imagery.

1.1 Data Sources

USGS Earth Explorer

1.2 Sources Referenced

The code in this analysis was adapted from the following sources below:

Wildfire Severity Analysis

Landsat Remote Sensing tif Files in R

1.3 Additional Contributors

Conservation Data Lab, Randy Swaty, Sam Ettenborough

2 Setup

Please review the README.md document for installation and setup instructions.

3 Importing Landsat Files

Code
# GEE project title
project <- "ee-samettenborough"

# fire 1 coordinates
fire_1 <- list(-91.253, 16.8194, -89.4018, 18.2112)

# pre fire start and end date search window
pre_start_date <- "2024-01-01"
pre_end_date <- "2024-03-01"

# output folder
out_dir <- "data/pre"

# # uncomment this section to re-download the images
# process_aoi(
#     project,
#     fire_1,
#     pre_start_date,
#     pre_end_date,
#     out_dir,
#     prefix="landsat_pre_",
# )

# pre fire start and end date search window
post_start_date <- "2024-08-01"
post_end_date <- "2024-10-01"

# output folder
out_dir <- "data/post"

# # uncomment this section to re-download the images
# process_aoi(
#     project,
#     fire_1,
#     post_start_date,
#     post_end_date,
#     out_dir,
#     filter_lim = 30,
#     prefix="landsat_post_",
# )

4 Visualize Pre and Post Images

Code
pre_fire_files <- list.files("data/pre",
                              full.names = TRUE)

pre_fires <- pre_fire_files |>
  map(rast) |>
  reduce(mosaic)

|---------|---------|---------|---------|
=========================================
                                          
Code
# Plotting in RGB to test
par(col.axis = 'white', col.lab = 'white', tck = 0)
plotRGB(pre_fires,
        r= 2, g= 1, b= 1,
        stretch = 'lin',
        axes = TRUE,
        main = 'Prefire RGB Composite Image, Bands 5,7')

Code
post_fire_files <- list.files("data/post",
                              full.names = TRUE)

post_fires <- post_fire_files |>
  map(rast) |>
  reduce(mosaic)

|---------|---------|---------|---------|
=========================================
                                          
Code
par(col.axis = 'white', col.lab = 'white', tck = 0)
plotRGB(post_fires,
        r= 2, g= 1, b= 1,
        stretch = 'lin',
        axes = TRUE,
        main = 'Postfire RGB Composite Image, Bands 5,7')

5 Calculate Normalized Burn Ratio and Burn Severity (dNBR)

Code
# Calculating the Delta Normalized Burn Ratio Index 
nbr_pre <- 1000 * (pre_fires[[1]] - pre_fires[[2]]) / 
  (pre_fires[[1]] + pre_fires[[2]])

nbr_post <- 1000 * (post_fires[[1]] - post_fires[[2]]) / 
  (post_fires[[1]] + post_fires[[2]])

# Attempt to calculate the Differenced Normalized Burn Ratio Index
dnbr <- (nbr_pre)-(nbr_post)

6 Display Pre and Post Fires

Code
nbr_stack <- c(nbr_pre, nbr_post)
names(nbr_stack) <- c("Pre-fire NBR", "Post-fire NBR")
nbr_stack_df <- rasterdf(nbr_stack)

|---------|---------|---------|---------|
=========================================
                                          
Code
ggplot(nbr_stack_df) +
  geom_raster(aes(x = x, 
                  y = y, 
                  fill = value)) + 
  scale_fill_gradient(name = "NBR", 
                       low = "lightyellow", 
                       high = "darkgreen") +
  coord_sf(expand = FALSE) +
  annotation_scale(location = 'bl') +
  facet_wrap(facets = vars(variable), 
             ncol = 1) +
  theme_void()

7 Display dNBR

Code
dnbr_df <- rasterdf(dnbr)

ggplot(dnbr_df) +
  geom_raster(aes(x = x, 
                  y = y, 
                  fill = value)) + 
  scale_fill_gradient2(name = "DNBR", 
                       low = "blue", 
                       high = "red",
                       midpoint = 0) +
  coord_sf(expand = F) +
  annotation_scale(location = 'bl') +
  theme_void()

8 Classify Severity

Code
# Classifying the index values into a matrix
rclas <- matrix(c(-Inf, -970, NA,  # Missing data
                  -970, -100, 5,   # Increased greenness
                  -100, 80, 1,     # Unburned
                  80, 265, 2,      # Low severity
                  265, 490, 3,     # Moderate severity
                  490, Inf, 4),    # High severity
                ncol = 3, byrow = T)

severity <- classify(dnbr, rclas)

SCcolors = c("darkgreen", 
             "cyan3", 
             "yellow", 
             "red", 
             "green")
SCnames = c("Unburned", 
            "Low", 
            "Moderate", 
            "High", 
            "> Green")
severity_df <- rasterdf(severity)

ggplot(severity_df) +
  geom_raster(aes(x = x, 
                  y = y, 
                  fill = as.character(value))) + 
  scale_fill_manual(name = "Severity Class",
                    values = SCcolors,
                    labels = SCnames,
                    na.translate = FALSE) +
  annotation_scale(location = 'bl') +
  coord_fixed(expand = F) +
  theme_void()